#include "config.h"
#include <stdio.h>
#include "params/params_inc.h"
#include "params/img_in_5.h"

INT8  img_in_q[1][32][32]={0};
INT32 c1_dout_q[6][28][28]={0};
dtype c1_dout[6][28][28]={0.0f};
INT8  c2_din_q[6][14][14]={0};
dtype c2_din[6][14][14]={0.0f};
INT32 c2_dout_q[6][28][28]={0};
dtype c2_dout[16][10][10]={0.0f};
dtype fc1_din[400];
dtype fc1_dout[120];
dtype fc2_dout[84];
dtype fc3_dout[10];

void input_data_quant(){
    for (int i = 0; i < 32 * 32; i++){
        int tmp = (int) (((dtype *)img_in)[i] * 127.0);
        if (tmp < -128)
            tmp = -128;
        if (tmp > 127)
            tmp = 127;
        ((INT8 *)img_in_q)[i] = tmp;
        // printf("%d,", ((INT8 *)img_in_q)[i]);
    }
}

void c2_din_quant(){
    for (int i = 0; i < 32 * 32; i++){
        int tmp = (int) (((dtype *)c2_din)[i] * 127);
        if (tmp < -128)
            tmp = -128;
        if (tmp > 127)
            tmp = 127;
        ((INT8 *)c2_din_q)[i] = tmp;
    }
}



int main(int argc, char const *argv[])
{
    input_data_quant(); // 将输入数据量化
    lenet_c1_int8(
        (INT8 (*)[32][32])img_in_q,
        (INT8 (*)[1][5][5])c1_weight,
        (INT32 (*)[28][28])c1_dout_q);
    lenet_c1_bias_relu(
        (INT32 (*)[28][28])c1_dout_q,
        (dtype *)c1_bias,
        (dtype)c1_weight_scale / 127.0,
        (dtype (*)[28][28])c1_dout);
    lenet_mp1(
        (dtype (*)[28][28])c1_dout,
        (dtype (*)[14][14])c2_din);
    c2_din_quant(); // c2层输入量化
    lenet_c2_int8(
        (INT8 (*)[14][14])c2_din_q,
        (INT8 (*)[6][5][5])c2_weight,
        (INT32 (*)[10][10])c2_dout_q);
    lenet_c2_bias_relu(
        (INT32 (*)[10][10])c2_dout_q,
        (dtype *)c2_bias,
        (dtype)c2_weight_scale / 127.0,
        (dtype (*)[10][10])c2_dout);
    lenet_mp2(
        (dtype (*)[10][10])c2_dout,
        (dtype (*)[5][5])fc1_din);

    lenet_fc1(
        (dtype (*))fc1_din,
        (dtype (*))fc1_dout,
        (dtype (*)[400])fc1_weight,
        (dtype (*))fc1_bias);
    lenet_fc2(
        (dtype (*))fc1_dout,
        (dtype (*))fc2_dout,
        (dtype (*)[120])fc2_weight,
        (dtype (*))fc2_bias);
    lenet_fc3(
        (dtype (*))fc2_dout,
        (dtype (*))fc3_dout,
        (dtype (*)[84])fc3_weight,
        (dtype (*))fc3_bias);

    int arg_max = 0;
    dtype max_val = 0;
    for (int i = 0; i < 10; i++){
        if (max_val < fc3_dout[i]){
            max_val = fc3_dout[i];
            arg_max = i;
        }
        printf("%f\n", fc3_dout[i]);
    }
    printf("arg max = %d\n", arg_max);
    
    
    return 0;
}

